package com.ma.controller;

import com.github.pagehelper.PageInfo;
import com.ma.common.dto.SysRoleDto;
import com.ma.common.lang.Const;
import com.ma.common.lang.Result;
import com.ma.entity.SysMenu;
import com.ma.entity.SysRole;
import com.ma.entity.SysRoleMenu;
import com.ma.service.SysRoleService;
import org.springframework.beans.factory.annotation.Autowired;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/sys/role")
@Slf4j
public class SysRoleController extends BaseController{

    @Autowired
    private SysRoleService sysRoleService;

    /*
    获取角色详细信息接口
    */
    @GetMapping("/info/{id}")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result info(@PathVariable(value = "id")Long id) {
        //根据id查询角色信息
        SysRole sysRole=sysRoleService.selectAllById(id);

        //获取角色相关联的菜单id
        //通过id查询角色菜单关联表
        List<SysRoleMenu> sysRoleMenuList = sysRoleMenuService.selectMenuIdByRoleId(id);

        SysRoleDto sysRoleDto=new SysRoleDto();
        sysRoleDto.setId(sysRole.getId());
        sysRoleDto.setName(sysRole.getName());
        sysRoleDto.setCode(sysRole.getCode());
        sysRoleDto.setRemark(sysRole.getRemark());
        sysRoleDto.setCreated(sysRole.getCreated());
        sysRoleDto.setUpdated(sysRole.getUpdated());
        sysRoleDto.setStatu(sysRole.getStatu());

        List<Long> ids=new ArrayList<>();
        for (SysRoleMenu sysRoleMenu : sysRoleMenuList) {
            if ( sysMenuService.getAllByparentId(sysRoleMenu.getMenuId()) <=0){
                ids.add(sysRoleMenu.getMenuId());
            }
        }
        sysRoleDto.setMenuIds(ids);

        return Result.succ(sysRoleDto);
    }

    /*
            根据username角色信息信息
            并进行分页操作
     */
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result listByUsername(@RequestParam(value = "name",required = false)String username,
                                 @RequestParam(value = "current",defaultValue = "1")  Integer page,
                                 @RequestParam(value = "size",defaultValue = "10")  Integer rows){
        if (page <=1){
            page=1;
        }
        PageInfo<SysRole> pageInfo = sysRoleService.listByUsername(username, page, rows);
        return Result.succ(pageInfo);
    }

    /*
            获取角色信息接口
     */
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('sys:role:save')")
    public Result save(@Validated @RequestBody SysRole sysRole) {
        sysRole.setCreated(new Date());
        sysRole.setStatu(Const.status_ON);
        sysRoleService.save(sysRole);
        return Result.succ("添加成功");
    }
     /*
             获取修改角色信息接口
     */
    @PostMapping("/update")
    @PreAuthorize("hasAuthority('sys:role:update')")
    @Transactional
    public Result update(@Validated @RequestBody SysRole sysRole) {
        sysRole.setUpdated(new Date());
        sysRoleService.update(sysRole);
        //更新缓存
        sysUserService.clearUserAuthorityInfoByRoleId(sysRole.getId());
        return Result.succ("修改成功");
    }
     /*
              获取角色信息删除接口
     */
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    @Transactional //保证事务要么执行要么回退
    public Result delete(@RequestBody Long[] ids) {
        for (Long id : ids) {
            System.out.println(id);
            sysRoleService.delete(id);

            //删除中间表
            sysRoleMenuService.deleteRoleMenuByRoleId(id);
            sysUserRoleService.deleteUserRoleByRoleId(id);
            //缓存同步删除
            sysUserService.clearUserAuthorityInfoByRoleId(id);
        }
        return Result.succ("删除成功");

    }

     /*
           管理角色权限接口
     */
    @Transactional
    @PostMapping("/perm/{roleId}")
    @PreAuthorize("hasAuthority('sys:role:perm')")
   // @PreAuthorize("hasRole('admin')")
    public Result save(@PathVariable(value = "roleId") Long roleId,@RequestBody Long[] menuIds) {
        /*
            先把menuIds的数组拆分
            在用list集合存储权限信息
            在删除原来存在的权限信息
         */
        List<SysRoleMenu> sysRoleMenuList=new ArrayList<>();
        for (Long menuId : menuIds) {

            SysRoleMenu sysRoleMenu=new SysRoleMenu();
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenu.setRoleId(roleId);
            sysRoleMenuList.add(sysRoleMenu);
        }

        //通过角色id删除原来存储的权限信息
        sysRoleMenuService.deleteRoleMenuByRoleId(roleId);
        log.info("删除原来存储的权限信息");
        //存储权限信息
        for (SysRoleMenu sysRoleMenu : sysRoleMenuList) {

            //通过菜单id查询到父id
            SysMenu sysMenu =sysMenuService.selectParentIdById(sysRoleMenu.getMenuId());//sysRoleMenu9  -sysMenu父2

            //父id等于0 说明为顶级菜单 直接存储
            if (sysMenu.getParentId() ==0L){
                log.info("顶级菜单"+sysMenu);
                sysRoleMenuService.saveByRoleMenuList(sysRoleMenu);
            }else {
                //不是顶级菜单，就去查询他的父id,父id不为0，则先直接存储这条权限信息  sysRoleMenu9-sysMenu父2
                sysRoleMenuService.saveByRoleMenuList(sysRoleMenu); //sysRoleMenu 9

                //用这条信息的父id查询他的父id  //sysMenu父2 --sysMenuTwo父1
                SysMenu sysMenuTwo = sysMenuService.selectParentIdById(sysMenu.getParentId());//sysMenuTwo 2---1
                if (sysMenuTwo.getParentId() != 0L) {
                    SysRoleMenu sysRoleMenuTwo = new SysRoleMenu(); //sysRoleMenuTwo 2
                    sysRoleMenuTwo.setMenuId(sysMenu.getParentId());
                    sysRoleMenuTwo.setRoleId(roleId);
                    sysRoleMenuService.saveByRoleMenuList(sysRoleMenuTwo);

                    //用这条信息再去查 //1--查0
                    SysMenu sysMenuTHree = sysMenuService.selectParentIdById(sysMenuTwo.getParentId());
                    if (sysMenuTHree.getParentId() == 0L) {
                        SysRoleMenu sysRoleMenuTHree = new SysRoleMenu(); //sysRoleMenuTwo 2
                        sysRoleMenuTHree.setMenuId(sysMenuTwo.getParentId());
                        sysRoleMenuTHree.setRoleId(roleId);
                        sysRoleMenuService.saveByRoleMenuList(sysRoleMenuTHree);

                    }
                }
            }

        }

        //清除缓存信息
        sysUserService.clearUserAuthorityInfoByRoleId(roleId);

        return Result.succ("添加成功");
    }
}
